package channelEntity

// SerialStreamEntity 注意：这个流实体必须由单个线程中去操作，不能多线程去同时操作它
type SerialStreamEntity struct {
	buff []byte
	end  int
	size int
}

func (e *SerialStreamEntity) New(size int) *SerialStreamEntity {
	ptr := &SerialStreamEntity{}
	ptr.buff = make([]byte, size)
	ptr.size = size
	ptr.end = 0
	return ptr
}

func (e *SerialStreamEntity) IsEmpty() bool {
	return e.end == 0
}

func (e *SerialStreamEntity) GetBuff() []byte {
	return e.buff
}

func (e *SerialStreamEntity) GetEnd() int {
	return e.end
}

func (e *SerialStreamEntity) AddTail(data []byte) {
	size := len(data)
	if size == 0 {
		return
	}

	// 检查：是否会溢出，如果要发生溢出，说明这个数据可能已经异常了，没有人能处理了，直接废弃吧
	if e.end+size > e.size {
		e.end = 0
	}

	copy(e.buff[e.end:e.end+size], data[0:size])
	e.end += size
}

func (e *SerialStreamEntity) MovHead(data []byte) {
	size := len(data)
	if size == 0 {
		return
	}

	if e.size < size {
		return
	}

	// 寻找data在buff中的位置，因为前面可能有其他垃圾数据
	index := -1
	for i := 0; i < e.size-size; i++ {
		find := true
		for j := 0; j < size; j++ {
			if data[j] == e.buff[i+j] {
				continue
			}
			find = false
			break
		}

		if find {
			index = i
			break
		}
	}
	if index < 0 {
		index = 0
	}

	// 截取数据：就是移动后面的数据到前面去
	copy(e.buff, e.buff[index+size:])
	e.end -= index + size
}
